package org.agle4j.framework.utils;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.CSVRecord;

/**
 * 描述：CSV 导入导出工具类
 * @author zte
 * @version 1.0
 */
public class CsvUtil {


    private static final String NEW_LINE_SEPARATOR = "\n";

    /**
     * CSV 文件读取
     *
     * @param filePath 要读取的csv文件 全路径
     * @param headers  csv文件中列名称数组
     * @return
     */
    public static List<Map<String, String>> readCsvFile(String filePath, String[] headers) {
        List<Map<String, String>> mapList = new ArrayList<>();
        if (new File(filePath).exists()) { // 判断读取文件是否存在
            // 这里显式地配置一下CSV文件的Header，然后设置跳过Header（要不然读的时候会把头也当成一条记录）
        	CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR).withHeader(headers).withSkipHeaderRecord();
			try (Reader reader = new FileReader(filePath)) {
				Iterable<CSVRecord> records = format.parse(reader);
				for (CSVRecord record : records) {
					Map<String, String> map = new HashMap<>();
					for (String header : headers) {
						map.put(header, record.get(header));
					}
					mapList.add(map);
				}
			} catch (Exception e) {
				throw new RuntimeException("readCsvFile failure", e);
			}
        }
        return mapList;
    }

    /**
     * 写入CSV文件, 默认使用Map的key为 列名称
     *
     * @param filePath 要生成的CSV文件 全路径
     * @param list     导入的数据
     * @return
     */
    public static boolean writeCsvFile(String filePath, List<Map<String, String>> list) {
        if (CollectionUtils.isNotEmpty(list)) {
            return writeCsvFile(filePath, list, list.get(0).keySet().toArray(new String[0]));
        }
        return false;
    }

    /**
     * 写入CSV文件,根据headers生成列名称
     *
     * @param filePath 要生成的CSV文件 全路径
     * @param list     导入的数据
     * @param headers  要生成的列名称
     * @return
     */
    public static boolean writeCsvFile(String filePath, List<Map<String, String>> list, String[] headers) {
        if (CollectionUtils.isNotEmpty(list)) {
            // 这里显式地配置一下CSV文件的Header，然后设置跳过Header（要不然读的时候会把头也当成一条记录）
        	CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR).withHeader(headers).withSkipHeaderRecord();
            try (Writer out = new FileWriter(filePath);
                 CSVPrinter printer = new CSVPrinter(out, format)) {
				printer.printRecord(headers);
                for (Map<String, String> map : list) {
                    List<String> records = new ArrayList<>();
                    for (String value : map.values()) {
                        records.add(value);
                    }
                    printer.printRecord(records);
                }
                return true;
            } catch (Exception e) {
                throw new RuntimeException("writeCsvFile failure", e);
            }
        }
        return false;
    }

    /**
     * 写入CSV文件,根据实体集合导入
     * @param filePath 要生成的CSV文件 全路径
     * @param list     导入的数据
     * @return
     */
    public static <T> boolean writeCsvFileByEntity(String filePath, List<T> list) {
        if (CollectionUtils.isNotEmpty(list)) {
            List<String> columnList = new ArrayList<>();
            for (Field field : list.get(0).getClass().getDeclaredFields()) {
                columnList.add(field.getName());
            }
            // 这里显式地配置一下CSV文件的Header，然后设置跳过Header（要不然读的时候会把头也当成一条记录）
            CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR).withHeader(columnList.toArray(new String[0])).withSkipHeaderRecord();
            try (Writer out = new FileWriter(filePath);
                 CSVPrinter printer = new CSVPrinter(out, format)) {
                printer.printRecord(columnList.toArray(new String[0]));
                for (T t : list) {
                    List<String> records = new ArrayList<>();
                    for (Field field : t.getClass().getDeclaredFields()) {
                        records.add(String.valueOf(PropertyUtils.getProperty(t, field.getName())));
                    }
                    printer.printRecord(records);
                }
                return true;
            } catch (Exception e) {
                throw new RuntimeException("writeCsvFileByEntity failure", e);
            }
        }
        return false;
    }

	public static void main(String[] args) {
		String[] FILE_HEADER1 = { "用户名", "名称", "年龄" };
		List<Map<String, String>> list = readCsvFile("E:\\aaaaaaaaaaa.csv", FILE_HEADER1);
		writeCsvFile("E://users1121.csv", list);
	}
}
